#!/usr/bin/env python3

import os, sys
import logging
import copy
import tqdm
import multiprocessing

logging.basicConfig(
    level=logging.DEBUG,
    format="%(asctime)s [%(levelname)s]: %(message)s",
    datefmt="%Y-%m-%d %H:%M:%S",
)
n_thread = max(1, os.cpu_count() - 1)

class BaseLevel:
    def __init__(self):
        self.level1_list = [0]
        self.level2_list = [0]
        self.level3_list = [0]
        self.level4_list = [0]
        self.level5_list = [0]
        self.level6_list = [0]
        self.min_start = 0
        self.max_end = 0
    
    def __str__(self):
        buffer = f"level1_list={self.level1_list}\n"
        buffer += f"level1_list={self.level2_list}\n"
        buffer += f"level1_list={self.level3_list}\n"
        buffer += f"level1_list={self.level4_list}\n"
        buffer += f"level1_list={self.level5_list}\n"
        buffer += f"level1_list={self.level6_list}\n"
        return buffer
    
    def set_level1_list(self, level:list)->None:
        self.level1_list = copy.deepcopy(level)

    def set_level2_list(self, level:list)->None:
        self.level2_list = copy.deepcopy(level)

    def set_level3_list(self, level:list)->None:
        self.level3_list = copy.deepcopy(level)

    def set_level4_list(self, level:list)->None:
        self.level4_list = copy.deepcopy(level)

    def set_level5_list(self, level:list)->None:
        self.level5_list = copy.deepcopy(level)

    def set_level6_list(self, level:list)->None:
        self.level6_list = copy.deepcopy(level)

    def set_last_loop(self, begin, end):
        self.min_start = begin
        self.max_end = end


class Implement1(BaseLevel):
    def __init__(self):
        self.large_list = []
        super().__init__()  # Call parent __init__() method

    def __str__(self):
        return super().__str__()    # Call parent __str__() method
    
    def pack_large_list(self):
        self.large_list.clear()

        for level1 in self.level1_list:
            for level2 in self.level2_list:
                for level3 in self.level3_list:
                    for level4 in self.level4_list:
                        for level5 in self.level5_list:
                            for level6 in self.level6_list:
                                for item in range(self.min_start, self.max_end + 1):
                                    self.large_list.append(
                                        f"{level1}:{level2}:{level3}:{level4}:{level5}:{level6}:{item}"
                                    )
        logging.critical(f"Encape large list complete. len={len(self.large_list)}")

    def execute_case(self, itemstr)->bool:
        return True
    
    def execute(self):
        logging.critical(f"Execute thread number: {n_thread}")
        
        with multiprocessing.Pool(processes=n_thread) as pool:
            with tqdm.tqdm(total=len(self.large_list)) as pbar:
                def update_progress(result):
                    pbar.update(1)
                for item in self.large_list:
                    pool.apply_async(self.execute_case, args=(item,), callback=update_progress)
                pool.close()    # Close pool
                pool.join()     # Wait for all process complete.



if __name__ == "__main__":
    test = Implement1()

    test.set_level1_list([1,2])
    test.set_level2_list([1,2])
    test.set_level3_list([1,2])
    test.set_level4_list([1,2])
    test.set_level5_list([1,2])
    test.set_level6_list([1,2])
    test.set_last_loop(1, 10000)

    test.pack_large_list()
    test.execute()

    print(test)
    print("main")

